package com.pay.controller;

import com.pay.config.wxpay.MyConfig;
import com.pay.config.wxpay.WXPay;
import com.pay.model.interface_parameter.*;
import com.pay.model.interface_return.WxPayQueryReturn;
import com.pay.service.inter.WeixinpayService;
import com.pay.utils.CodeEnum;
import com.pay.utils.validate.annotation.PrintParameter;
import com.pay.utils.validate.annotation.ValidateParameter;
import com.pay.utils.validate.vali_util.ValidateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;


/**
 * 微信支付
 *
 * @author MENG
 * @version 2018/7/11
 * @see
 */
@RestController
public class WeixinpayController
{
    Logger logger = LoggerFactory.getLogger(WeixinpayController.class);

    @Autowired
    private WeixinpayService weixinpayService;

    /**
     * 获取微信支付生成的二维码
     *
     * 参数：WxPayQrCodeParam
     *
     * 返回：WxPayQrCodeReturn
     */
    @RequestMapping("getWxPayQrCode")
    @ValidateParameter
    @PrintParameter(description = "获取微信支付生成的二维码")
    public Map<String,Object> getWxPayQrCode(@RequestBody WxPayQrCodeParam wxPayQrCodeParam)
    {
        return weixinpayService.scanPay(wxPayQrCodeParam.getAppId(),wxPayQrCodeParam.getMchId(),wxPayQrCodeParam.getApiKey(),wxPayQrCodeParam.getNotifyUrl(),wxPayQrCodeParam.getOrderNo(),wxPayQrCodeParam.getTotalAmount(),wxPayQrCodeParam.getSubject(),wxPayQrCodeParam.getQrCodeTimeoutExpress());
    }


    /**
     * 手机H5支付唤起微信支付
     *
     * 参数：WxPayQrCodeParam 待测试
     *
     * 返回：WxPayQrCodeReturn
     */
    @RequestMapping("wxPayMobileWeb")
    @ValidateParameter
    @PrintParameter(description = "手机H5微信支付")
    public Map<String,Object> wxPayMobileWeb(@RequestBody WxPayMobileWebParam wxPayMobileWebParam)
    {
        return weixinpayService.wxPayMobileWeb(wxPayMobileWebParam.getAppId(),wxPayMobileWebParam.getMchId(),wxPayMobileWebParam.getApiKey(),wxPayMobileWebParam.getNotifyUrl(),wxPayMobileWebParam.getOrderNo(),wxPayMobileWebParam.getTotalAmount(),wxPayMobileWebParam.getSubject(),wxPayMobileWebParam.getTimeoutExpress(),wxPayMobileWebParam.getSceneInfo());
    }


    /**
     * 微信内部浏览器支付
     *
     * 参数：WxPayQrCodeParam 待测试
     *
     * 返回：WxPayQrCodeReturn
     */
    @RequestMapping("wxPayMobileWechatWeb")
    @ValidateParameter
    @PrintParameter(description = "手机微信中H5支付")
    public Map<String,Object> wxPayMobileWechatWeb(@RequestBody WxPayMobileWechatParam wxPayMobileWechatParam)
    {
        return weixinpayService.wxPayMobileWechatWeb(wxPayMobileWechatParam.getAppId(),wxPayMobileWechatParam.getMchId(),wxPayMobileWechatParam.getApiKey(),wxPayMobileWechatParam.getNotifyUrl(),wxPayMobileWechatParam.getOrderNo(),wxPayMobileWechatParam.getTotalAmount(),wxPayMobileWechatParam.getSubject(),wxPayMobileWechatParam.getTimeoutExpress(),wxPayMobileWechatParam.getSceneInfo(),wxPayMobileWechatParam.getOpenId());
    }

    /**
     * 微信付款码支付
     *
     * 参数：WxPayAuthCodeParam
     *
     * 返回：WxPayAuthCodeReturn
     *
     * @return
     */
    @RequestMapping("wxPayAuthCode")
    @ValidateParameter
    @PrintParameter(description = "微信付款码支付")
    public Map<String,Object> wxPayAuthCode(@RequestBody WxPayAuthCodeParam wxPayAuthCodeParam)
    {
        return weixinpayService.weixinCode(wxPayAuthCodeParam.getAppId(),wxPayAuthCodeParam.getMchId(),wxPayAuthCodeParam.getApiKey(),wxPayAuthCodeParam.getNotifyUrl(),wxPayAuthCodeParam.getOrderNo(),wxPayAuthCodeParam.getTotalAmount(),wxPayAuthCodeParam.getSubject(),wxPayAuthCodeParam.getAuthCode(),wxPayAuthCodeParam.getTimeoutExpress());
    }

    /**
     * 微信支付退款
     *
     * 参数：WxPayRefundParam
     *
     * 返回：WxPayRefundReturn
     * @return
     */
    @RequestMapping("wxPayRefund")
    @ValidateParameter
    @PrintParameter(description = "微信支付退款")
    public Map<String,Object> wxPayRefund(@RequestBody WxPayRefundParam wxPayRefundParam)
    {
        return weixinpayService.weixinRefund(wxPayRefundParam.getAppId(),wxPayRefundParam.getMchId(),wxPayRefundParam.getApiKey(),wxPayRefundParam.getOrderNo(),wxPayRefundParam.getRefundAmount(),wxPayRefundParam.getRefundReason());
    }

    /**
     * 微信支付退款
     *
     * 参数：WxPayRefundParam
     *
     * 返回：WxPayRefundReturn
     * @return
     */
    @RequestMapping("wxPayRebate")
    @ValidateParameter
    @PrintParameter(description = "微信支付部分退款")
    public Map<String,Object> wxPayRebate(@RequestBody WxPayRebateParam wxPayRebateParam)
    {
        return weixinpayService.wxPayRebate(wxPayRebateParam.getAppId(),wxPayRebateParam.getMchId(),wxPayRebateParam.getApiKey(),wxPayRebateParam.getOrderNo(),wxPayRebateParam.getRefundAmount(),wxPayRebateParam.getRefundReason(),wxPayRebateParam.getTotalAmount(),wxPayRebateParam.getSunOrderCode());
    }



    /**
     * 订单支付状态查询
     *
     * 参数：WxPayQueryParam
     *
     * 返回：WxPayQueryReturn
     * @return
     */
    @RequestMapping("wxPayQuery")
    @ValidateParameter
    @PrintParameter(description = "微信支付状态查询")
    public Map<String,Object> wxPayQuery(@RequestBody WxPayQueryParam wxPayQueryParam)
    {
        WxPayQueryReturn wxPayQueryReturn = new WxPayQueryReturn();

        wxPayQueryReturn.setOrderNo(wxPayQueryParam.getOrderNo());

        MyConfig config = new MyConfig();

        config.setAppId(wxPayQueryParam.getAppId());

        config.setMchId(wxPayQueryParam.getMchId());

        config.setApiKey(wxPayQueryParam.getApiKey());

        WXPay wxpay = null;

        String resXml = "";

        try
        {
            wxpay = new WXPay(config);

            //重新查询支付订单  确实是否支付成功
            Map<String, String> data = new HashMap<String, String>();

            data.put("out_trade_no", wxPayQueryParam.getOrderNo());

            //查询
            Map<String, String> resp = wxpay.orderQuery(data);

            String returnCode = resp.get("return_code");

            if("SUCCESS".equals(returnCode))
            {
                String resultCode = resp.get("result_code");

                if("SUCCESS".equals(resultCode))
                {
                    String trade_state = resp.get("trade_state");

                    if("SUCCESS".equals(trade_state))
                    {
                        //支付成功
                        wxPayQueryReturn.setPayStatus("1");

                        return ValidateUtil.returnSuccess(wxPayQueryReturn);
                    }
                    else if("USERPAYING".equals(trade_state))
                    {
                        wxPayQueryReturn.setPayStatus("2");

                        return ValidateUtil.returnSuccess(wxPayQueryReturn);
                    }
                    else
                    {
                        wxPayQueryReturn.setPayStatus("3");

                        return ValidateUtil.returnSuccess(wxPayQueryReturn);
                    }
                }
                else
                {
                    String errMsg = resp.get("err_code_des");

                    String errCode = resp.get("err_code");

                    logger.error("微信支付查询接口失败");

                    logger.error("ERROR_CODE ："+ errCode + "、ERROR_MSG ：" + errMsg);

                    return ValidateUtil.returnError(CodeEnum.WXPAY_QUERY_ORDER_STATUS_FAILE.getCode(),CodeEnum.WXPAY_QUERY_ORDER_STATUS_FAILE.getMessage());
                }
            }
            else
            {
                logger.error("微信支付查询API调用失败");

                String errMsg = resp.get("return_msg");

                logger.error("ERROR_MSG ：" + errMsg);

                return ValidateUtil.returnError(CodeEnum.INVOKE_WXPAY_QUERY_ORDER_STATUS_FAILE.getCode(),CodeEnum.INVOKE_WXPAY_QUERY_ORDER_STATUS_FAILE.getMessage());
            }
        }
        catch (Exception e)
        {
            logger.error("微信支付状态查询错误",e);

            return ValidateUtil.returnError(CodeEnum.WXPAY_QUERY_ORDER_STATUS_ERROR.getCode(),CodeEnum.WXPAY_QUERY_ORDER_STATUS_ERROR.getMessage());
        }
    }


//    @Value("${update.order.url}")
//    private String updateOrderUrl;
//
//    @Value("${update.order.dubious.url}")
//    private String updateOrderDubiousUrl;

//    /**
//     * 微信通知
//     * @param request
//     * @param response
//     */
//    @RequestMapping("wxpayNotify")
//    public void wxpayNotify(HttpServletRequest request, HttpServletResponse response)
//    {
//        logger.info("收到微信支付通知。。。。");
//
//        // 读取参数
//        InputStream inputStream = null;
//
//        try
//        {
//            inputStream = request.getInputStream();
//
//            StringBuffer sb = new StringBuffer();
//
//            String s = "";
//
//            BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
//
//            while ((s = in.readLine()) != null)
//            {
//                sb.append(s);
//            }
//
//            in.close();
//
//            inputStream.close();
//
//
//            MyConfig config = new MyConfig();
//
//            config.setAppId(MyConfig.appIdCache);
//
//            config.setMchId(MyConfig.mchIdCache);
//
//            config.setApiKey(MyConfig.apiKeyCache);
//
//            WXPay wxpay = new WXPay(config);
//
//            Map<String, String> notifyMap = WXPayUtil.xmlToMap(sb.toString());  // 转换成map
//
//            logger.info("API KEY : " + MyConfig.apiKeyCache);
//
//            logger.info("notifyMap 得到的参数 : ");
//
//            for (String key : notifyMap.keySet())
//            {
//                logger.info(key + " :  " + notifyMap.get(key));
//            }
//
//            if (wxpay.isPayResultNotifySignatureValid(notifyMap))
//            {
//                logger.info("微信支付成功回调");
//
//                logger.info("result_code : " + (String) notifyMap.get("result_code"));
//
//                // 签名正确
//                // 进行处理。
//                // 注意特殊情况：订单已经退款，但收到了支付结果成功的通知，不应把商户侧订单状态从退款改成支付成功
//                String resXml = "";
//
//                if ("SUCCESS".equals((String) notifyMap.get("result_code")))
//                {
//                    // 这里是支付成功
//                    String orderNo = (String) notifyMap.get("out_trade_no");
//
//                    Map<String,Object> resultMap = wxPayQuery(MyConfig.appIdCache,MyConfig.mchIdCache,MyConfig.apiKeyCache,orderNo);
//
//                    if(resultMap.get("resXml") != null && PayStatusConstants.paySucess.code.equals(resultMap.get(PayStatusConstants.codeKey)))
//                    {
//                        resXml = resultMap.get("resXml").toString();
//                    }
//                    else
//                    {
//                        //标记订单可疑
//                        //标记订单可疑
//                        logger.info("发送 标记订单可疑 http请求");
//
//                        Map paramsMap = new HashMap<>();
//
//                        paramsMap.put("orderCode",orderNo);
//
//                        //执行http 调用 标记订单可疑
//                        HttpClientUtils.httpRequest(updateOrderDubiousUrl,"POST",paramsMap);
//
//                        logger.info("http请求发送成功");
//                    }
//                }
//                else
//                {
//                    logger.info("支付失败,错误信息：{}",notifyMap.get("err_code"));
//
//                    resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
//                }
//
//                if(resXml == "")
//                {
//                    resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
//                }
//                // ------------------------------
//                // 处理业务完毕
//                // ------------------------------
//                BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
//
//                out.write(resXml.getBytes());
//
//                out.flush();
//
//                out.close();
//            }
//            else
//            {
//                // 签名错误，如果数据里没有sign字段，也认为是签名错误
//                logger.error("微信支付获取回调函数 验证 签名错误!");
//            }
//
//        }
//        catch (Exception e)
//        {
//            logger.error("微信支付获取回调函数执行错误!",e);
//        }
//    }

//    /**
//     *
//     * 微信小程序 下单
//     * https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1
//     *
//     * @param appId         微信分配的小程序ID
//     * @param mchId         微信支付分配的商户号
//     * @param apiKey        APIKEY
//     * @param subject       商品简单描述
//     * @param outTradeNo    商户系统内部订单号 要求32个字符内
//     * @param timeExpire    订单失效时间，格式为yyyyMMddHHmmss
//     * @param totalFee      订单总金额
//     * @param notifyUrl     异步接收微信支付结果通知的回调地址，通知url必须为外网可访问的url  需自己实现微信回调通知函数
//     * @param openid        用户在商户appid下的唯一标识 openId 获取地址（https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html）
//     *
//     *
//     */
//    @RequestMapping("wxAppletPay")
//    public void wxAppletPay(String appId,String mchId,String apiKey,String subject, String outTradeNo,String timeExpire,String totalFee,String notifyUrl,String openid)
//    {
//        logger.info("微信小程序下单");
//
//        weixinpayService.wxAppletPay(appId,mchId,apiKey,subject,outTradeNo,timeExpire,totalFee,notifyUrl,openid);
//
//    }

}
